package com.ds.udp;

import com.alibaba.fastjson.JSONObject;
import com.ds.cluster.udp.ClusterCommand;
import com.ds.command.Command;
import com.ds.common.JDSConstants;
import com.ds.common.JDSException;
import com.ds.common.expression.function.AbstractFunction;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.engine.ConnectInfo;
import com.ds.engine.JDSSessionHandle;
import com.ds.enums.CommandEnums;
import com.ds.esb.config.EsbBeanAnnotation;
import com.ds.esb.config.EsbFlowType;
import com.ds.iot.Device;
import com.ds.iot.ct.CtIotFactory;
import com.ds.org.Person;
import com.ds.org.PersonNotFoundException;
import com.ds.server.JDSClientService;
import com.ds.server.JDSServer;
import com.ds.server.OrgManagerFactory;
import com.ds.server.eumus.ConfigCode;

import java.util.List;
import java.util.Set;

@EsbBeanAnnotation(id = "RepeatCommand", name = "转发UDP命令", flowType = EsbFlowType.msgRepeat, expressionArr = "RepeatCommand(command)", desc = "转发UDP命令")
public class RepeatCommand extends AbstractFunction {
    private static final Log logger = LogFactory.getLog(JDSConstants.CONFIG_KEY, RepeatCommand.class);


    public Boolean perform(ClusterCommand command) {
        try {
            String commandStr = command.getCommand();
            if (CommandEnums.fromByName(commandStr) != null) {
                Command jdscommand = (Command) JSONObject.parseObject(command.getCommandJson(), CommandEnums.fromByName(commandStr).getCommand());
                Device device = CtIotFactory.getCtIotService().getDeviceByIeee(jdscommand.getGatewayieee());
                Person person = null;
                try {
                    person = OrgManagerFactory.getOrgManager().getPersonByAccount(device.getBindingaccount());
                } catch (PersonNotFoundException e) {
                    e.printStackTrace();
                }
                ConnectInfo connectInfo = new ConnectInfo(person.getID(), person.getAccount(), person.getPassword());
                Set<JDSSessionHandle> sessionHandleList = JDSServer.getInstance().getSessionHandleList(connectInfo);

                int k = 0;
                while (sessionHandleList.size() == 0 && k < command.getMaxtimes()) {
                    try {
                        Thread.sleep(command.getTimeout());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                    sessionHandleList = JDSServer.getInstance().getSessionHandleList(connectInfo);
                }
                for (JDSSessionHandle sessionHandle : sessionHandleList) {
                    JDSClientService client = JDSServer.getInstance().getJDSClientService(sessionHandle, ConfigCode.gw);
                    if (client.getConnectInfo() != null && client.getConnectionHandle().isconnect()) {
                        try {
                            Device gatewaydevice = CtIotFactory.getCtIotService().getDeviceById(client.getConnectInfo().getLoginName());
                            String gwieee = jdscommand.getGatewayieee();
                            if (gatewaydevice != null) {
                                if (gwieee == null || gwieee.equals(gatewaydevice.getSerialno())) {
                                    client.getConnectionHandle().send(jdscommand);
                                } else {
                                    logger.error("gwiee error gatewaydevice.getSerialno()=[" + gatewaydevice.getSerialno() + "] gwieee=" + gwieee);
                                }
                            } else {
                                client.getConnectionHandle().send(jdscommand);
                            }

                        } catch (JDSException e) {
                            client.getConnectionHandle().send(jdscommand);
                        }
                    }
                }
            } else {
                logger.error("[" + command.getCommand() + "] not a suport command!");
            }

        } catch (JDSException e) {
            e.printStackTrace();
        }
        return true;

    }

}
